home *** CD-ROM | disk | FTP | other *** search
- /* $Id: vector.c,v 1.7 89/09/20 17:49:22 mbp Exp $
- *
- * vector.c: vector procedures
- */
-
- /************************************************************************
- * Copyright (C) 1989 by Mark B. Phillips *
- * *
- * Permission to use, copy, modify, and distribute this software and *
- * its documentation for any purpose and without fee is hereby granted, *
- * provided that the above copyright notice appear in all copies and *
- * that both that copyright notice and this permission notice appear in *
- * supporting documentation, and that the name of Mark B. Phillips or *
- * the University of Maryland not be used in advertising or publicity *
- * pertaining to distribution of the software without specific, written *
- * prior permission. This software is provided "as is" without express *
- * or implied warranty. *
- ************************************************************************/
-
- #include <math.h>
- #include "lgd.h"
- #include "internal.h"
- #include "vector.h"
-
- #define PI 3.1415927
- #define DEGTORAD(x) (PI*x/180)
- #define YES 1
- #define NO 0
-
-
- /* NOTE: All vectors in this file are assumed to have dimension
- * lgd_dim. */
-
- /*-----------------------------------------------------------------------
- * Function: LGD_copy_vec
- * Description: vector copy operation
- * Args IN: v2: source
- * OUT: v1: destination
- */
- LGD_copy_vec( v1, v2 )
- double v1[],v2[];
- {
- int i;
-
- for (i=0; i<lgd_dim; ++i) v1[i] = v2[i];
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: LGD_add_vec
- * Description: vector addition
- * Args IN: v2,v3: summands
- * OUT: v1: the sum v2 + v3
- */
- LGD_add_vec( v1, v2, v3 )
- double v1[],v2[],v3[];
- {
- int i;
-
- for (i=0; i<lgd_dim; ++i)
- v1[i] = v2[i] + v3[i];
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_sub_vec
- * Description: vector subtraction
- * Args IN: v2,v3: vectors to be subtracted
- * OUT: v1: the difference v2 - v3
- */
- LGD_sub_vec( v1, v2, v3 )
- double v1[], v2[], v3[];
- {
- int i;
- for (i=0; i<lgd_dim; ++i)
- v1[i] = v2[i] - v3[i];
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_L2norm_vec
- * Description: L2 (Euclidean) norm of a vector
- * Args IN: v: a vector
- * Returns: it's norm
- */
- double
- LGD_L2norm_vec( v )
- double v[];
- {
- return( sqrt( LGD_dotprod_vec( v, v ) ) );
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_L2dist_vec
- * Description: L2 (Euclidean) distance between vectors
- * Args IN: v1,v2: two vectors
- * Returns: the distance between them
- */
- double
- LGD_L2dist_vec( v1, v2 )
- double v1[], v2[];
- {
- double v[3];
- LGD_sub_vec( v, v1, v2 );
- return( LGD_L2norm_vec( v ) );
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: LGD_dotprod_vec
- * Description: dot product (regular old dot product)
- * Args IN: v1,v2: two vectors
- * Returns: their dot product
- */
- double
- LGD_dotprod_vec( v1, v2 )
- double v1[], v2[];
-
- {
- int i;
- double val;
- for (i=0, val=0; i<lgd_dim; ++i)
- val += v1[i] * v2[i];
- return(val);
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: LGD_unit_vec
- * Description: unitize a vector
- * Args IN: v: a vector
- * OUT: v: unit vector having same direction as original v
- */
- LGD_unit_vec( v )
- double v[];
- {
- LGD_scamul_vec( v, 1.0/LGD_L2norm_vec( v ), v );
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: LGD_scamul_vec
- * Description: multiply a vector by a scalar
- * Args IN: s: a scalar
- * v2: a vector
- * OUT: v1: s times v2
- */
- LGD_scamul_vec( v1, s, v2 )
- double v1[], s, v2[];
- {
- int i;
- for (i=0; i<lgd_dim; ++i)
- v1[i] = s*v2[i];
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_mult_matrix4x4
- * Description: multiply two 4x4 matrices
- * Args IN: B,C: the factors
- * OUT: A: the product B*C
- */
- LGD_mult_matrix4x4(A, B, C)
- double A[4][4], B[4][4], C[4][4];
- {
- register int i,j,k;
-
- for (i=0; i<4; ++i)
- for (j=0; j<4; ++j) {
- A[i][j] = 0;
- for (k=0; k<4; ++k)
- A[i][j] += B[i][k] * C[k][j];
- }
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_matmul_vec
- * Description: multiply a (3x3) matrix by a vector
- * Args IN: M: a 3x3 matrix
- * v2: a vector
- * OUT: v1: the product M*v2
- */
- LGD_matmul_vec( v1, M, v2 )
- double v1[3], M[3][3], v2[3];
- {
- int i,j;
- for (i=0; i<3; ++i) {
- v1[i] = 0;
- for (j=0; j<3; ++j)
- v1[i] += M[i][j]*v2[j];
- }
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: LGD_cross_vec
- * Description: vector cross product
- * Args IN: v2,v3: two vectors
- * OUT: v1: the cross produc v2 x v3
- */
- LGD_cross_vec( v1, v2, v3 )
- double v1[], v2[], v3[];
- {
- v1[0] = v2[1] * v3[2] - v2[2] * v3[1];
- v1[1] = v2[2] * v3[0] - v2[0] * v3[2];
- v1[2] = v2[0] * v3[1] - v2[1] * v3[0];
- }
-
- /*-----------------------------------------------------------------------
- * Function: LGD_compute_3d_rot_mat
- * Description: compute 3x3 rotation matrix about axis through origin
- * Args IN: u: direction of axis of rotation
- * deg: angle of rotation, in degrees
- * OUT: M: the rotation matrix
- * Notes: 1. Positive angles give counterclockwise rotation as
- * seen from the end of u looking towards the origin.
- * 2. u need not be a unit vector
- */
- LGD_compute_3d_rot_mat( M, u, deg )
- double M[3][3], u[3], deg;
- {
- double unit_u[3], costh, sinth, u1sq, u2sq, u3sq;
- double u1u2, u1u3, u2u3, one_minus_costh;
-
- #define u1 unit_u[0]
- #define u2 unit_u[1]
- #define u3 unit_u[2]
-
- LGD_copy_vec( unit_u, u );
- LGD_unit_vec( unit_u );
- costh = cos( DEGTORAD(deg) );
- sinth = sin( DEGTORAD(deg) );
- one_minus_costh = 1 - costh;
- u1sq = u1 * u1;
- u2sq = u2 * u2;
- u3sq = u3 * u3;
- u1u2 = u1 * u2;
- u1u3 = u1 * u3;
- u2u3 = u2 * u3;
- /* row 1: */
- M[0][0] = u1sq + costh * ( 1 - u1sq );
- M[0][1] = u1u2 * one_minus_costh - u3*sinth;
- M[0][2] = u1u3 * one_minus_costh + u2*sinth;
- /* row 2: */
- M[1][0] = u1u2 * one_minus_costh + u3*sinth;
- M[1][1] = u2sq + costh * ( 1 - u2sq );
- M[1][2] = u2u3 * one_minus_costh - u1*sinth;
- /* row 3: */
- M[2][0] = u1u3 * one_minus_costh - u2*sinth;
- M[2][1] = u2u3 * one_minus_costh + u1*sinth;
- M[2][2] = u3sq + costh * ( 1 - u3sq );
-
- #undef u1
- #undef u2
- #undef u3
- }
-